package cn.jdemo.io.outputstream;

import cn.jdemo.io.inpustream.Demo07_ObjectInputStream;

import java.io.*;

/**
 * @see OutputStream 抽象基类
 * @see DataOutput ObjectOutput的父接口
 * @see ObjectOutput ObjectOutputStream的父接口
 * @see ObjectStreamConstants ObjectOutputStream的父接口,写入对象序列化流的常量
 * @see ObjectOutputStream 数据是格式化的
 * (1)实例化需要OutputStream流对象
 * (2)用于将数据从任何Java原语类型转换为一系列字节
 * (3)ObjectOutputStream与ObjectInputStream配合，可进行文件序列化：
 *      (a)持久到磁盘---与FileOutputStream、FileInputStream配合使用;
 *      @see Demo06_ObjectOutputStream#test03()
 *      (b)保存到内存(深度克隆)---与ByteArrayOutputStream、ByteArrayInputStream配合使用
 *      @see cn.jdemo.io.util.CloneUtil#clongObj(Object)
 *
 *
 * // 构造方法
 * @see ObjectOutputStream#ObjectOutputStream(OutputStream)
 * @see ObjectOutputStream#ObjectOutputStream() protected作用域
 *
 * @see ObjectOutputStream#writeObject(Object)
 *
 * // 包含OutputStream常用方法
 * // 包含DataOutput常用方法
 *
 * @date 2020/12/21
 */
public class Demo06_ObjectOutputStream {
    public static void main(String[] args) throws IOException {
        // test01();
        // test02();
        test03();
    }


    /**
     * 输出内容:
     * A.toString:cn.jdemo.io.outputstream.A@2db0f6b2
     *
     * @throws IOException
     */
    public static void test01() throws IOException {
        try(ObjectOutputStream dataOS = new ObjectOutputStream(new FileOutputStream("D:\\A.txt"));){
            // 写入
            A a = new A("a",10);
            System.out.println("A.toString:"+a.toString());
            dataOS.writeObject(a);
        }catch (IOException ex){
        }
    }

    /**
     * 输出内容:
     * A.toString:cn.jdemo.io.outputstream.A@2db0f6b2
     * java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: cn.jdemo.io.outputstream.A
     * 	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1571)
     * 	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
     * 	at cn.jdemo.io.inpustream.Demo07_ObjectInputStream.test01(Demo07_ObjectInputStream.java:34)
     * 	at cn.jdemo.io.outputstream.Demo06_ObjectOutputStream.test02(Demo06_ObjectOutputStream.java:70)
     * 	at cn.jdemo.io.outputstream.Demo06_ObjectOutputStream.main(Demo06_ObjectOutputStream.java:32)
     * Caused by: java.io.NotSerializableException: cn.jdemo.io.outputstream.A
     * 	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
     * 	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
     * 	at cn.jdemo.io.outputstream.Demo06_ObjectOutputStream.test02(Demo06_ObjectOutputStream.java:65)
     * 	... 1 more
     *
     * @see cn.jdemo.io.inpustream.Demo07_ObjectInputStream
     *
     */
    public static void test02() throws IOException {
        try(ObjectOutputStream dataOS = new ObjectOutputStream(new FileOutputStream("D:\\A.txt"));){
            // 写入
            A a = new A("a",10);
            System.out.println("A.toString:"+a.toString());
            dataOS.writeObject(a);
        }catch (IOException ex){
        }

        // 读取
        Object obj = Demo07_ObjectInputStream.test01("D:\\A.txt");
        if (obj instanceof A){
            A a2 = (A) obj;
            System.out.println("A.toString:"+a2.toString());
        }
    }

    /**
     * 输出内容:
     * B.toString:cn.jdemo.io.outputstream.B@2db0f6b2
     * B.toString:cn.jdemo.io.outputstream.B@38082d64
     *
     * 注:readObject的数据必须序列化
     */
    public static void test03() throws IOException {
        try(ObjectOutputStream dataOS = new ObjectOutputStream(new FileOutputStream("D:\\B.javaObj"));){
            // 写入
            B b = new B("b",10);
            System.out.println("B.toString:"+b.toString());
            dataOS.writeObject(b);
        }catch (IOException ex){
        }

        // 读取
        Object obj = Demo07_ObjectInputStream.test01("D:\\B.javaObj");
        if (obj instanceof B){
            B b2 = (B) obj;
            System.out.println("B.toString:"+b2.toString());
        }
    }
}

class A{
    String name;
    int age;
    public A(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

class B implements Serializable{
    static final long serialVersionUID = -6430539691155161871L;
    String name;
    int age;
    public B(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}